﻿/******************************************************************************              
 * Author: 671643387@qq.com                                                                                                                                            
 * @MR.Luo                                                                                      
 *****************************************************************************/

#include <stdio.h>
#if defined(__WINDOWS__)
#include <crtdbg.h>
#endif
#include <signal.h>
#include <vector>
#include <boost/program_options.hpp>
#include "Common.h"
using namespace dev;
namespace po = boost::program_options;


bool useAtomic = false;
volatile int viVal = 0;

class AtomicThread : public dev::base::Thread
{
public:
    AtomicThread(void){}
    ~AtomicThread(void){}

public:
    virtual void stop(void){}
    virtual void run(void)
    {
        dev::base::Thread::sleep(100);
        if (useAtomic)
            dev::base::atom_inc32((uint32_t*)&viVal);
        else
            ++viVal;
    }
};

typedef boost::shared_ptr<AtomicThread> AtomicThreadPtr;

int main(int argc, char *argv[])
{
    int workerCount = 0;
    bool useAtomic = false;

    po::options_description desc("allow options");
    desc.add_options()
        ("help,h", "show usage")
        ("threads,t", po::value<int>()->default_value(1), "number of thread to run")
        ("atomic,a", po::value<bool>()->default_value(false), "use atomic");

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);

    if (vm.count("help"))
    {
        std::cout << desc << std::endl;
        return 0;
    }

    if (vm.count("threads"))
    {
        workerCount = vm["threads"].as<int>();
    }

    if (vm.count("atomic"))
    {
        useAtomic = vm["atomic"].as<bool>();
    }

#if defined(__WINDOWS__)
    //_CrtSetBreakAlloc(156);
#endif
	__DV_TRY
    {
        std::vector<AtomicThreadPtr> threads;        
        for (int i = 0; i < workerCount; ++i)
        {
            AtomicThreadPtr thread(new AtomicThread());
            threads.push_back(thread);

            thread->start();
        }

        for (std::vector<AtomicThreadPtr>::iterator it = threads.begin(); it != threads.end(); ++it)
        {
            (*it)->join();
        }

        printf("%d thread, %d\n", workerCount, viVal);
	}
	__DV_CATCH(std::exception& e)
	{
		__DV_DUMP(e);
	}

#if defined(__WINDOWS__)
	_CrtDumpMemoryLeaks();
#endif

	return 0;
}
